#define _LINUX_ 

#include <cstdio>
#include <cstring>
#include <cstdlib>

/**** CAMBIAR PARA ARBOL *****/
#include "Hash/c_dato.h"
#include "Hash/c_hash.h"
/* ******************************************************************************************** */
/* Para modificar el tama�o del bloque ver el archivo constantes.h                              */
/* LARGO_BLOQUE                                                                                 */ 
/* ******************************************************************************************** */

char  * nombre_archivo=NULL;
int cod_exit=0;


/* ******************************************************************************************** */

/* AGREGA registro A LA LISTA DE registroS A INDEXAR */
int agregar_registro(const char* clave, const char* valor )
{


c_hash* arch_hash = new c_hash(nombre_archivo);   
c_dato dato ( atoi(clave), (char*) valor ); 

printf ("...Agregando clave: %s, valor: %s \n",clave,valor);

arch_hash->insertar_dato(&dato);

delete arch_hash;

return cod_exit;
}

/* ELIMINAR UN registro DE LA LISTA A INDEXAR */

int modificar_registro(const char* clave, const char* valor )
{


c_hash* arch_hash = new c_hash(nombre_archivo);   
c_dato dato ( atoi(clave), (char*) valor ); 

arch_hash->modificar_dato(&dato);

delete arch_hash;

return cod_exit;
}

int quitar_registro(const char* clave)
{

c_hash* arch_hash = new c_hash(nombre_archivo);   

c_dato dato ( atoi(clave), NULL ); 
arch_hash->eliminar_dato(&dato);

delete arch_hash;


return cod_exit;
}

int buscar_registro(const char* clave)
{

c_hash* arch_hash = new c_hash(nombre_archivo);   
c_dato dato ( atoi(clave), NULL ); 
arch_hash->buscar_dato(&dato);

delete arch_hash;


return cod_exit;
}

/*********************************************  FIN CAMBIAR PARA ARBOL ***************************************************/


int parser_registros( int operacion )
{

char buffer[2][LARGO_BLOQUE];
int pos_buffer[2];
int c;
int token=-1;

pos_buffer[0]=0;
pos_buffer[1]=0;


while ( ((c=getc(stdin))!=EOF)||(c==0) )
	{
	    switch (c) 
		{
    		    case  '(':  if(token==-1) token=0;
    			        break;
    			        
		    case  ';':  if (token==0) { token=1; 
		    				buffer[0][pos_buffer[0]]=0;
		    			       }	    
		    						                
		                break;
		    case  ')':  if (token==1) { token=2;
						buffer[1][pos_buffer[1]]=0;
					       }	
		                break;
		                
		    default  :  if ( (token==0) || (token==1) && pos_buffer[token]<LARGO_BLOQUE-1)  
								 buffer[token][pos_buffer[token]++]=c;		    
				else if (token==2)
					{
					 
					 if (operacion==OP_AGREGAR)
					 			agregar_registro ( (const char*) buffer[0] , (const char*) buffer[1] );

				         else if (operacion==OP_MODIFICAR)

				                                modificar_registro ( (const char*) buffer[0] , (const char*) buffer[1] );
				         else if (operacion==OP_QUITAR)
				                                quitar_registro ( (const char*) buffer[0] );

				         else if (operacion==OP_BUSCAR)
				                                buscar_registro ( (const char*) buffer[0] );

				                                
				         pos_buffer[0]=0;
					 pos_buffer[1]=0;

				         token=-1;
					}					
				break;            		                		                
		}				
	  
	}
	
return 0;
}


int listar_registro ()
{

char archivo_txt[]="./log.txt";

FILE* handler_txt = fopen (archivo_txt,"w+");

if (handler_txt)
    {
    printf ("Generando archivo %s...\n",archivo_txt);    

    c_hash arch_hash(nombre_archivo);   

    arch_hash.dump(handler_txt);

    fclose(handler_txt);
    } else printf ("Error al Generar archivo %s",archivo_txt);
    
return cod_exit;

}





/* LINEA DE COMANDOS */
int mostrar_opciones (char * nombre_del_programa)
{
	  printf ("\nUsar: %s  NombreArchivo [opciones] ",nombre_del_programa);
	  printf ("\n-I clave valor\n\t Ingresa datos a la estructura");
	  printf ("\n-B clave \n\t Busca datos a la estructura");
	  printf ("\n-M clave valor\n\t Modifica datos a la estructura");
	  printf ("\n-Q clave \n\t Quita un dato de la estructura");
	  printf ("\n-S\n\t Vuelca los datos de la estructura a texto ");
	  
	  printf ("\n");
return 0;
}



int main (int argc, char **argv)
{

int arg_pl=0; int arg_pa=0; int arg_pd=0;  int arg_pm=0; int arg_pb=0; 
int i;
char* clave=NULL;
char* valor=NULL;

    if (argc <= 2)
	{
	  mostrar_opciones (argv[0]);
	  return 0;
	}
    else

	{
	    nombre_archivo=argv[1];
	    
	    for (i=2;i<argc;i++)
		{
	              if(arg_pa) {  if (clave==NULL) clave=argv[i];
                                      else 
                                       { 	        	 
	        	 	        valor=argv[i];	        	              	        	              	        	                
	        	                printf ("\n\tDato a agregar. clave: %s valor: %s \n",clave,valor);	        		      
	        		        agregar_registro(clave,valor);	        		      	        		        
	        		        arg_pa=0;
	        		        }
    	    			    }


	            else if(arg_pm) { if (clave==NULL) clave=argv[i];
                                      else 
                                       { 	        	 
	        	 	        valor=argv[i];	        	              	        	              	        	                
	        	                printf ("\n\tDato a modificar. clave: %s valor: %s \n",clave,valor);	        		      
	        		        modificar_registro(clave,valor);	        		      	        		        
	        		        arg_pm=0;
	        		        }
    	    			    }


	            else if(arg_pd) { clave=argv[i];
	                              
	                              printf ("\n\tDato a eliminar. %s\n",clave);	        		      
	        		      quitar_registro(clave);	        		      
	        		      arg_pd=0;
    	    			    }


	            else if(arg_pb) { clave=argv[i];
	                              
	                              printf ("\n\tDato a buscar. %s\n",clave);	        		      
	        		      buscar_registro(clave);	        		      
	        		      arg_pb=0;
    	    			    }




		    else if (!strcmp(argv[i],"-S")) {
						arg_pl=1;
					        printf ("\n Opcion -S: Mostrar los datos de la estructura\n");
					        listar_registro ();
		    				}		    						    				
		    				
		    else if (!strcmp(argv[i],"-I")) {
					
						if(i>=argc-1)
						        { 
						           printf ("\n Opcion -I: Ingresar datos a la estructura (carga de stdin)\n");
						           parser_registros(OP_AGREGAR);						        						        						        
							}
						else
							{
						    arg_pa=1;
					    	    printf ("\n Opcion -I: Ingresar datos a la estructura");
							}    
						}		    						    		

		    else if (!strcmp(argv[i],"-M")) 
		    				if(i>=argc-1)
						        { 
						           printf ("\n Opcion -I: Ingresar datos a la estructura (carga de stdin)\n");
						           parser_registros(OP_MODIFICAR);						        						        						        
							}		    
						else {
						arg_pm=1;
					        printf ("\n Opcion -M: Modifica un dato de la estructura");
		    				}
		    				
		    else if (!strcmp(argv[i],"-Q")) 
		    				if(i>=argc-1)
						        { 
						           printf ("\n Opcion -I: Ingresar datos a la estructura (carga de stdin)\n");
						           parser_registros(OP_QUITAR);						        						        						        
							}
						else

						
						{
						arg_pd=1;
					        printf ("\n Opcion -Q: Quita un dato de la estructura");
		    				}

		    else if (!strcmp(argv[i],"-B")) 
		    				if(i>=argc-1)
						        { 
						           printf ("\n Opcion -B: Busca datos a la estructura (carga de stdin)\n");
						           parser_registros(OP_BUSCAR);						        						        						        
							}
						else

						
						{
						arg_pb=1;
					        printf ("\n Opcion -B: Busca un dato de la estructura");
		    				}
		    				
		    				
		    				
		    				
		    				
		    else if (!strcmp(argv[i],"-h")) {
						    mostrar_opciones (argv[0]);
					        
		    				}




		    else 	{

					        printf ("\n Opcion invalida\n");
					    
					        return(-1);
			        }



		}

	  }

	  return (cod_exit);
}
